home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / HTMLParser.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  10KB  |  296 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. import markupbase
  5. import re
  6. interesting_normal = re.compile('[&<]')
  7. interesting_cdata = re.compile('<(/|\\Z)')
  8. incomplete = re.compile('&[a-zA-Z#]')
  9. entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]')
  10. charref = re.compile('&#(?:[0-9]+|[xX][0-9a-fA-F]+)[^0-9a-fA-F]')
  11. starttagopen = re.compile('<[a-zA-Z]')
  12. piclose = re.compile('>')
  13. commentclose = re.compile('--\\s*>')
  14. tagfind = re.compile('[a-zA-Z][-.a-zA-Z0-9:_]*')
  15. attrfind = re.compile('\\s*([a-zA-Z_][-.:a-zA-Z_0-9]*)(\\s*=\\s*(\\\'[^\\\']*\\\'|"[^"]*"|[-a-zA-Z0-9./,:;+*%?!&$\\(\\)_#=~@]*))?')
  16. locatestarttagend = re.compile('\n  <[a-zA-Z][-.a-zA-Z0-9:_]*          # tag name\n  (?:\\s+                             # whitespace before attribute name\n    (?:[a-zA-Z_][-.:a-zA-Z0-9_]*     # attribute name\n      (?:\\s*=\\s*                     # value indicator\n        (?:\'[^\']*\'                   # LITA-enclosed value\n          |\\"[^\\"]*\\"                # LIT-enclosed value\n          |[^\'\\">\\s]+                # bare value\n         )\n       )?\n     )\n   )*\n  \\s*                                # trailing whitespace\n', re.VERBOSE)
  17. endendtag = re.compile('>')
  18. endtagfind = re.compile('</\\s*([a-zA-Z][-.a-zA-Z0-9:_]*)\\s*>')
  19.  
  20. class HTMLParseError(Exception):
  21.     
  22.     def __init__(self, msg, position = (None, None)):
  23.         self.msg = msg
  24.         self.lineno = position[0]
  25.         self.offset = position[1]
  26.  
  27.     
  28.     def __str__(self):
  29.         result = self.msg
  30.         if self.lineno is not None:
  31.             result = result + ', at line %d' % self.lineno
  32.         
  33.         if self.offset is not None:
  34.             result = result + ', column %d' % (self.offset + 1)
  35.         
  36.         return result
  37.  
  38.  
  39.  
  40. class HTMLParser(markupbase.ParserBase):
  41.     CDATA_CONTENT_ELEMENTS = ('script', 'style')
  42.     
  43.     def __init__(self):
  44.         self.reset()
  45.  
  46.     
  47.     def reset(self):
  48.         self.rawdata = ''
  49.         self.lasttag = '???'
  50.         self.interesting = interesting_normal
  51.         markupbase.ParserBase.reset(self)
  52.  
  53.     
  54.     def feed(self, data):
  55.         self.rawdata = self.rawdata + data
  56.         self.goahead(0)
  57.  
  58.     
  59.     def close(self):
  60.         self.goahead(1)
  61.  
  62.     
  63.     def error(self, message):
  64.         raise HTMLParseError(message, self.getpos())
  65.  
  66.     __starttag_text = None
  67.     
  68.     def get_starttag_text(self):
  69.         return self._HTMLParser__starttag_text
  70.  
  71.     
  72.     def set_cdata_mode(self):
  73.         self.interesting = interesting_cdata
  74.  
  75.     
  76.     def clear_cdata_mode(self):
  77.         self.interesting = interesting_normal
  78.  
  79.     
  80.     def goahead(self, end):
  81.         rawdata = self.rawdata
  82.         i = 0
  83.         n = len(rawdata)
  84.         while i < n:
  85.             match = self.interesting.search(rawdata, i)
  86.             if match:
  87.                 j = match.start()
  88.             else:
  89.                 j = n
  90.             if i < j:
  91.                 self.handle_data(rawdata[i:j])
  92.             
  93.             i = self.updatepos(i, j)
  94.             if i == n:
  95.                 break
  96.             
  97.             startswith = rawdata.startswith
  98.             None if startswith('<', i) else match
  99.             if startswith('&', i):
  100.                 match = entityref.match(rawdata, i)
  101.                 if match:
  102.                     name = match.group(1)
  103.                     self.handle_entityref(name)
  104.                     k = match.end()
  105.                     if not startswith(';', k - 1):
  106.                         k = k - 1
  107.                     
  108.                     i = self.updatepos(i, k)
  109.                     continue
  110.                 
  111.                 match = incomplete.match(rawdata, i)
  112.                 if match:
  113.                     if end and match.group() == rawdata[i:]:
  114.                         self.error('EOF in middle of entity or char ref')
  115.                     
  116.                     break
  117.                 elif i + 1 < n:
  118.                     self.handle_data('&')
  119.                     i = self.updatepos(i, i + 1)
  120.                 else:
  121.                     break
  122.             match
  123.         if end and i < n:
  124.             self.handle_data(rawdata[i:n])
  125.             i = self.updatepos(i, n)
  126.         
  127.         self.rawdata = rawdata[i:]
  128.  
  129.     
  130.     def parse_pi(self, i):
  131.         rawdata = self.rawdata
  132.         match = piclose.search(rawdata, i + 2)
  133.         if not match:
  134.             return -1
  135.         
  136.         j = match.start()
  137.         self.handle_pi(rawdata[i + 2:j])
  138.         j = match.end()
  139.         return j
  140.  
  141.     
  142.     def parse_starttag(self, i):
  143.         self._HTMLParser__starttag_text = None
  144.         endpos = self.check_for_whole_start_tag(i)
  145.         if endpos < 0:
  146.             return endpos
  147.         
  148.         rawdata = self.rawdata
  149.         self._HTMLParser__starttag_text = rawdata[i:endpos]
  150.         attrs = []
  151.         match = tagfind.match(rawdata, i + 1)
  152.         k = match.end()
  153.         self.lasttag = tag = rawdata[i + 1:k].lower()
  154.         while k < endpos:
  155.             m = attrfind.match(rawdata, k)
  156.             if not m:
  157.                 break
  158.             
  159.             (attrname, rest, attrvalue) = m.group(1, 2, 3)
  160.             if not rest:
  161.                 attrvalue = None
  162.             elif "'" == "'":
  163.                 pass
  164.             elif not "'" == attrvalue[-1:]:
  165.                 if '"' == '"':
  166.                     pass
  167.                 elif '"' == attrvalue[-1:]:
  168.                     attrvalue = attrvalue[1:-1]
  169.                     attrvalue = self.unescape(attrvalue)
  170.                 
  171.             attrs.append((attrname.lower(), attrvalue))
  172.             k = m.end()
  173.             continue
  174.             attrvalue[:1]
  175.         end = rawdata[k:endpos].strip()
  176.         if end not in ('>', '/>'):
  177.             (lineno, offset) = self.getpos()
  178.             if '\n' in self._HTMLParser__starttag_text:
  179.                 lineno = lineno + self._HTMLParser__starttag_text.count('\n')
  180.                 offset = len(self._HTMLParser__starttag_text) - self._HTMLParser__starttag_text.rfind('\n')
  181.             else:
  182.                 offset = offset + len(self._HTMLParser__starttag_text)
  183.             self.error('junk characters in start tag: %r' % (rawdata[k:endpos][:20],))
  184.         
  185.         if end.endswith('/>'):
  186.             self.handle_startendtag(tag, attrs)
  187.         else:
  188.             self.handle_starttag(tag, attrs)
  189.             if tag in self.CDATA_CONTENT_ELEMENTS:
  190.                 self.set_cdata_mode()
  191.             
  192.         return endpos
  193.  
  194.     
  195.     def check_for_whole_start_tag(self, i):
  196.         rawdata = self.rawdata
  197.         m = locatestarttagend.match(rawdata, i)
  198.         if m:
  199.             j = m.end()
  200.             next = rawdata[j:j + 1]
  201.             if next == '>':
  202.                 return j + 1
  203.             
  204.             if next == '/':
  205.                 if rawdata.startswith('/>', j):
  206.                     return j + 2
  207.                 
  208.                 if rawdata.startswith('/', j):
  209.                     return -1
  210.                 
  211.                 self.updatepos(i, j + 1)
  212.                 self.error('malformed empty start tag')
  213.             
  214.             if next == '':
  215.                 return -1
  216.             
  217.             if next in 'abcdefghijklmnopqrstuvwxyz=/ABCDEFGHIJKLMNOPQRSTUVWXYZ':
  218.                 return -1
  219.             
  220.             self.updatepos(i, j)
  221.             self.error('malformed start tag')
  222.         
  223.         raise AssertionError('we should not get here!')
  224.  
  225.     
  226.     def parse_endtag(self, i):
  227.         rawdata = self.rawdata
  228.         match = endendtag.search(rawdata, i + 1)
  229.         if not match:
  230.             return -1
  231.         
  232.         j = match.end()
  233.         match = endtagfind.match(rawdata, i)
  234.         if not match:
  235.             self.error('bad end tag: %r' % (rawdata[i:j],))
  236.         
  237.         tag = match.group(1)
  238.         self.handle_endtag(tag.lower())
  239.         self.clear_cdata_mode()
  240.         return j
  241.  
  242.     
  243.     def handle_startendtag(self, tag, attrs):
  244.         self.handle_starttag(tag, attrs)
  245.         self.handle_endtag(tag)
  246.  
  247.     
  248.     def handle_starttag(self, tag, attrs):
  249.         pass
  250.  
  251.     
  252.     def handle_endtag(self, tag):
  253.         pass
  254.  
  255.     
  256.     def handle_charref(self, name):
  257.         pass
  258.  
  259.     
  260.     def handle_entityref(self, name):
  261.         pass
  262.  
  263.     
  264.     def handle_data(self, data):
  265.         pass
  266.  
  267.     
  268.     def handle_comment(self, data):
  269.         pass
  270.  
  271.     
  272.     def handle_decl(self, decl):
  273.         pass
  274.  
  275.     
  276.     def handle_pi(self, data):
  277.         pass
  278.  
  279.     
  280.     def unknown_decl(self, data):
  281.         self.error('unknown declaration: %r' % (data,))
  282.  
  283.     
  284.     def unescape(self, s):
  285.         if '&' not in s:
  286.             return s
  287.         
  288.         s = s.replace('<', '<')
  289.         s = s.replace('>', '>')
  290.         s = s.replace(''', "'")
  291.         s = s.replace('"', '"')
  292.         s = s.replace('&', '&')
  293.         return s
  294.  
  295.  
  296.